package com.sample.memcache.test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;

import net.spy.memcached.CASResponse;
import net.spy.memcached.CASValue;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.internal.OperationFuture;

public class MemcacheApi {
	static MemcachedClient c;

	static {
		try {
			c = new MemcachedClient(new InetSocketAddress("localhost", 11211));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * PostId must be unique
	 * @param userId
	 * @param postId
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public static void addPost(String userId, String postId)
			throws InterruptedException, ExecutionException {
		boolean added;
		do {
			CASValue<Object> counter = c.gets(getCounterKey(userId, postId));
			if (counter == null) {
				OperationFuture<Boolean> addCounter = c.add(
						getCounterKey(userId, postId), 3600, "0");
				if (addCounter.get() == false) {
					counter = c.gets(getCounterKey(userId, postId));
				} else {
					counter = new CASValue<Object>(c.gets(
							getCounterKey(userId, postId)).getCas(), "0");
				}
			}
			CASValue<Object> post = c.gets(getPostKey(userId, postId,
					(String) counter.getValue()));
			if (post == null) {
				OperationFuture<Boolean> addPost = c
						.add(getPostKey(userId, postId,
								(String) counter.getValue()), 3600, postId);
				if (addPost.get() == false) {
					post = c.gets(getPostKey(userId, postId,
							(String) counter.getValue()));
					added = c.prepend(
							post.getCas(),
							getPostKey(userId, postId,
									(String) counter.getValue()), postId + ",")
							.get();
				} else {
					added = true;
				}
			} else {
				if(post.getValue().toString().getBytes().length >= 500) {
					added = false;
				} else {
				added = c
						.prepend(
								post.getCas(),
								getPostKey(userId, postId,
										(String) counter.getValue()),
								postId + ",").get();
				}
			}
			if(!added) {
				c.cas(getCounterKey(userId, postId),counter.getCas() , String.valueOf((Integer.parseInt((String) counter.getValue()) + 1)));
			}
		} while (!added);

	}

	public static void main(String[] args) throws InterruptedException,
			ExecutionException {
//		c.delete(getCounterKey("userId", "postId"));
//		c.delete(getPostKey("userId", "postId", "0"));
		while(true) {
			addPost("userId", "postId");
			System.out.println(c.get(getPostKey("userId", "postId", "0")));
		}
	}

	private static String getPostKey(String userId, String postId,
			String counter) {
		StringBuilder builder = new StringBuilder("");
		return builder.append(userId).append("_").append(postId)
				.append(counter).toString();
	}

	private static String getCounterKey(String userId, String postId) {
		StringBuilder builder = new StringBuilder("");
		return builder.append(userId).append("_").append("post").append("_")
				.append("counter").toString();
	}

}
